package com.Pan.util;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

/**
 * 对称加密解密AES算法
 *
 * @author zhaors
 */
public class AESUtils {

    private static final String TRANSFORMATION = "AES/CBC/PKCS5Padding";
    private static final String ALGORITHM = "AES";
    private static final String CHARSET = "utf-8";
    private static String iv = "0123456789ABCDEF";//偏移量字符串必须是16位 当模式是CBC的时候必须设置偏移量
    private static String KEY = "1234567890ABCDEF";//密钥

    public static byte[] generatorKey() throws NoSuchAlgorithmException {
        KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM);
        keyGenerator.init(256);//默认128，获得无政策权限后可为192或256
        SecretKey secretKey = keyGenerator.generateKey();
        return secretKey.getEncoded();
    }

    public static IvParameterSpec getIv() throws UnsupportedEncodingException {
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes("utf-8"));
        System.out.println("偏移量："+byteToHexString(ivParameterSpec.getIV()));
        return ivParameterSpec;
    }

    public static byte[] encrypt(String src) throws NoSuchAlgorithmException, NoSuchPaddingException,
            InvalidKeyException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException, InvalidAlgorithmParameterException {
        byte[] key = KEY.getBytes("utf-8");
        SecretKey secretKey = new SecretKeySpec(key, ALGORITHM);
        IvParameterSpec ivParameterSpec = getIv();
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec);
        byte[] cipherBytes = cipher.doFinal(src.getBytes(Charset.forName(CHARSET)));
        return cipherBytes;
    }

    public static String decrypt(String src) throws Exception {
        byte[] key = KEY.getBytes("utf-8");
        SecretKey secretKey = new SecretKeySpec(key, ALGORITHM);
        IvParameterSpec ivParameterSpec = getIv();
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec);
        byte[] hexBytes = hexStringToBytes(src);
        byte[] plainBytes = cipher.doFinal(hexBytes);
        return new String(plainBytes, "utf-8");
    }

    /**
     * 将byte转换为16进制字符串
     * @param src
     * @return
     */
    public static String byteToHexString(byte[] src) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xff;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                sb.append("0");
            }
            sb.append(hv);
        }
        return sb.toString();
    }

    /**
     * 将16进制字符串装换为byte数组
     * @param hexString
     * @return
     */
    public static byte[] hexStringToBytes(String hexString) {
        hexString = hexString.toUpperCase();
        int length = hexString.length() / 2;
        char[] hexChars = hexString.toCharArray();
        byte[] b = new byte[length];
        for (int i = 0; i < length; i++) {
            int pos = i * 2;
            b[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
        }
        return b;
    }

    private static byte charToByte(char c) {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }

    public static void main(String[] args) {
        try {
            byte key[] = KEY.getBytes("utf-8");//hexStringToBytes("0123456789ABCDEF");
            String src = "你好啊";
            System.out.println("密钥:"+byteToHexString(key));
            System.out.println("原字符串:"+src);
            String enc = byteToHexString(encrypt(src));
            System.out.println("加密："+enc);
            System.out.println("解密："+decrypt("fda9904fa0b931b70e8d7a4539b6b4aa3802656512701a55bd9a7f0306a0823e21ce7a52d2041e74e217b9905aae0a22c11550d02728c69653f68b9463e99a82541476f97cfee62b7bc6e7b294e1751f95891de318a20883dc85eb4fe1c2c8bf746d23131ba74553b6e37cde3f0ade241b311eb9ae3749543bf66e83b6086ef4aab55f23f0f597589224919cddd55440a70a293e55dac049db7840721ecbeb5b9d5b29d6073c9381d00c8c374ed9d46f6faa5b1a2f3d77880bb96a93cd0eb14543d6bc06916361f1e3305c26f5cee4ab45de36be68024c5f4bf7d8a698215c81f6cec76cd52ffc3cfc59f61b690b125bc515d327a114c08528f02266ac6612800474d53e3a88bf187a2381465df246788b43f602243f1f91d119d1dec33f4600beeee36488c7b0f2adc4c89af0b00083000c51ca9d2d9698ed84a6184b4af56b0edafdd47a0d5483abaaff6bcc11f1934b0d81b4d3a25c772d21170c73d05dccf8c0d54a5a0a66cc9159fb2662ae0bf32899e9db5348bd99ebc8915a4f75605df7cb928877ee837953bc4283526e7464c05ae7a5f445222e95fb4f53af82f148de4c419045b486b475679a787535a50dbe5b30158f5a2542ca779e909cd7b9a8b74f3e7b9960ef6a2e2f1f2144d46e2f883ca6d7a6b5937d89141ad17d235132577e3f88bd542099e2fca7d00bea6df0b07084fc33f9bddf6eef3291a1e63ac87e13eb9851f6e37ad1cd23404390eba42d2c3f1a0ccf8284527ec1de5bac3f4b3cac86c26936e1c886ecfec6bd20a86029782c4991c9ecff562224d9e87758ff05a44d400b75d34e33ad3f3c96533f8291e611fb8491704ecb2d924b4d55c52746a309ec7e5665f4c9708ff4106c1f6badf51a5c3457fbcf3556ba2f51a9f444d6f29e42f0ff2775f10fe01aa73dd1838417193ebc169bee9c71fa141d731e2de9c7dcb9b2353cc43830feb781da9c96e94e58ca1724eb818f3b0e458598f60412c0e2a8fdd6411ce651a0905c31f750461098b6488ca200f0b8cc5409c3f8441ffc0703be5e99bcdb97efd78e33bad58bc7545861e26244ae47d329e91a51a589fdd66c5148a4116dfa2937dfa76e1db0584c52f1edfa040fe333dd1ddee8152ccb22319ee2fb38219a7194e052802f6ebd89bca15b9fb5fe1a6f243bdbf432011aa13ea2395a0acb6270ea1d8c282dfc60862c8601b2186fd2849c93b05eed0e137487267c1b910adeae0c27eb5db5ebcb77943e5da4fa764db5a0ebdf9fd3e2511c87e87c783e9da378a4548746801784deb69f2c3f6b2e9ed2e7cbdc5d6b462db74ab23fd4431d3b15f0e95012223e287e569c171e6fb09f288394d8e3f731f759c3d7a5c92e05b8a68171de37b7c4bfd6aa50e7d8522f2192031537a7ff856daca0de264a5e7ab17bcb511b22671733aba7b40179f16dc516f403f58e0930c26be10813b16286a5ab4037c0d26a81455accedcca9da1e607f3869825eb5b3a52c030892fb7296b1afbcc7e27a57a9955027b7af032c7d01fccfe16cc837366acece29d0ba050368f5cf2efab99977e8bb597168d22f0fd8aaf21510b0242261829f12924c96dae58ea5f68c6d99abe4aebd08399aba1a9435f31c658812222c87721d8f514d27e2ee6a408612c9f0470e47e22c07d2f5d93eaf70ff29f9acf5715cf9086528087995ebc52c6e131795b1a3ab2c9d386674daa3846cbd09f7a10c32f6b655800ee480b00bd6b79ac39ceb1c2b828f795f7bdf2c7b9ab601b6b24216d41e179bb469c40b5a009dac625559af79036acaa2dc134de9550c1ca3c58bf76990772d612d018dfef586c955f87dd6115e4fc6d93637aea4323c6736743ccb12b4b67209d555fdb9d30ba6c6c91393dbc1ef36b8ad668064f0ed26bb7eb2fdb343c123b8a6717bb629b572d851817bc0fd5498c7366224686cc6ab9e0119bf0fc2709575017334386f2b8ee04143151813ba4d97d8e4de6cb9d09ecaf3bdb6c825e206a6d5500298d116098a934ae866445b27ec0ccbfbaa7eaae445ea80f5e993d7d8eaeaffb95211b6d0ba12487ec8bc949f87f0201de8cab1a1bd5c0a99970b837dde2d79efb05055042b7120a970765c95c3277f645c7edf4265e00b6989e0564e277074dbc1cca7222915da4b74c5df1d7341e7d4efdb5129bf035d1bf8c3604425be2b1ff2a4932e23f94cb206051fc1ffacc4125d08028b812a61737f983c58b9f9f3029bc1c0dbad68a0bd5dbe6d5d1c652503aa78e852e15522d7f2c1acf0bc983a0c7793673960f11bf12e0ecab11522fc66ad6b70c35a66298f1fc4ad317cbff89f8011433039c905d56470e257a295aef021de5e16a2d48bacbd61302eb60a5df5ed49499ad3488cd105ef7dbf8c6daf81c347ec61c04202bb11733da1ce13dedca3615b256bc3a34e8702f0c7f98c2dcf54d86fbf59b0d9f248d1791b7c582858180daa7bb615dfeb1fa10ce8362e091d2fe9b692cd65fa8538612270dc2183f0fcef6ff5221fe9732899cdcb75bb99563816bce2a73e6623fe3f5bdf602cb011b5c201364dcc9321351f0f7cd95571fb3ddda63b959e3824a30e95327328f4731d647dfc0ae57a2ea1ebe4c5116ac391090b98b7f940ebd63ff950d2477d71f0884e0689937282bb0382300df7dfb619a7bb0e2bd346138ce317650cba520b0bfb1028ec7e5fa707a408983ad5fb63eeb99a9019fbed3bb5699bfaacc9380c34a397d01e3eed41fbabc55c6e16bac0ca71967a21704bb51707d3eb1279e406e5274457ae79a72ac33fa83ef30b52c01d4a375083d57270515a3d28b5a47ce5694aad8ed64506adfdd70c019221139e25f2bddaaed0cb731267d34b04379f7ddf1bcfd10744f10be0c7ccbb9e65bef44155a4c6e98d03e047b8c9d7d6962f46bde09e25dd2cc3553238a99b09ad41493c034fbfa9bb0b76a26c193bec7b2ce156df607034e33cb504af6f83598d21c3262da91fb8ad2b8f09465726f57790669a92e945f3476e578088674af19685c56b0445d97263904692bab2fb55d5441e25dfa663d84a027cbb3799a91bd5d25edc021d4ea595f51b7aa2ea8c9c8b39bccf856a86c03a1a11531717e990871d4e919357b9a583c79a3af18e52f21902a07c334d5364fda195291eb4cfc7c461512479662c83f65ff283f6fae8c616075a4802b267b0f318d2ed74dd2fe45c67d289f680e0e1c85765c0ecf95cea32745c59a8a2825f2dac932ffa4f6f8dc06f614ed0cfd990d84ccd178130acc310a43848542217dab3d43b7795bac3f258bf9d94e2a0eacfa2faa7830e071546651eae6fca5bc101442c1acd1e680728c468e8d38291c7bd10face24bfef1f83f9e4f86542255d58508bd6bcda4823f41950f4efb2a46cbb4eae3af8a81a556845980070742aa42cb877cc7154b2ecc3b224fdf8aba9a938a1f6fddb5d58091e48d841d9fda3ec2b236c78bd1d8a0dcf104607a373c87c7dd1bf8cd973bcdbd96f4a845648ef9cf3f41bae806c36ddd994c69d90230248e20473e5faaef11dda8ab793c2f8c2dc7f44b268a679686785cfbafb93cb18ab503c55370146878fb96f68718c0519e1f5c89a36159b72540e55695b4041eba9fdcca32e69c109253f18e4c508a4d8830885bdf7e8a3d9f7ca3dff885735bfa9ead8a3b4697ac181d50808c6910e4cf68c240342b7cfb9e5540cf6bb51affc057316c7c7d52b0600569f607ffac649c47917f6e0b34ede8304257bbca5b83aa9ffdb82d2a1b784822692ecb4ff385626e422691c1b6623e68e53619c1836d4d292d49cd5b7aeeb25e93fc08059a1ff3af53bbc72ac79eb1c9a217a869d5d2a61076994ad7a25b0d2225311c81ae5874310534599b8f50a7d3e9c299238f763dc13eda83ac3c50cf34fccfa741117744fedd08fb206308ba767294e97feee914a7aad3a415e2accbb41898faf23b5da175c5947f913f0989b20633c87e00c82205732e650feeaed4c74952db56377f6d65860c65bd524b211797cb0f669dbec8ddb311611711526e65baaaa7f99718ec251a000edf713b847022a5c72f5487de0d4e8b1613c065554c50765eb0e4c28e1b3a451622c18daafbd8ccb145de8db3ccb46d5e6b12d8b8bc8835d51b8729e0bdb9c854e16def17cd93d7c900e0c94ee3e6a8bf757efe2983be27c03fb0378f757936489ec3dc324b5bd589d9b5c87f433d9e3f2023762024a11812880a7be34cf764aefd0b6466678b198bfaf0423cc853b7ec253f9ac42c6c6fc31c78a48683f7e7ef64d30ecbed745bf89fa2f2c09e4023c92f485900d3b553a214f6995bf4a4512d7a50af46e5406887cbe78630c190af2c7716165a3788cbb9075298ec59c6f9112ab8363db1d7db08d583337ab09cc3fe3cb0c9bb945c670369ae1992f7f50a2286ce67c1137274201b4d4cb5e7e2f740c071e36ef082cb75cbc3ee9445ab48f88d2336aadc520026c2ff5aeb3b1511bbf6acc99c067b6ab21f01d63ac83df2d7ffe4e1b5a6bc9b7bc9d48bbaa9654c8bb704fd37f4150b3c3435f5273049f0f75beec3b6880cbd577dc0e251f66ea5402f15f8c8ce5304ac201907a8c020159d34125b57980a70219ac16eefa8e65952366676ec62aa11ab071e7ffc7c7741b5eac51fd812c547e6da9b58a9d2a60c0adbd8ec1d1d41de14a5bb067b9a7022a7665735132cc1b08b092ff57e337672f7f0f5f7c69b6a66d697056d34f108e6af6d2ca17827d1d7b36db7edb56cb17cd22306561909f12b2b5b2a3145282be017ad31ab7e837e9de04a6b356ce9773726318dd32f77b0f174de1c7caf880cd1ace21dfd71be4565cb9b7a3e7aedacd6e32bb169225ce38acac434d8f3ab4b1220a7ae916945612e0e24059d3e15b1a12ee1d2d7cf9180e13b3f27f5a4d66001aad0128a71ee9c5cc8de2008eb67dd40334527e0ed604d25f073701533531b4e3f8936aca0fa31c6833fa0f0a8ee2993df9d388228d18de26e7e1d74871fa2e387f50c484608ce0804e45602d24ccc36fc6ba20bf8dfbd34073652f47b6e158441ed4dd8264f2584d93e858e306432a948926912b89e68fd77f19222767454705420b6a07f6fde45c68617e4a445d4108cabce5de2a48d2f920485005e0bd6de657a1d4ee59c6adda030d0924950354fa20b4647baebd058f9571e8a77f11bfe3ee54b4cb56a06743cf405c7315d1bf43a4983f84ce86a3a90ec2537eef971eefbfe1c57d01e2245c745e1faf13012de6107c6605f4d4ca44c0c6e13ff943f29fd4e7990f81bf616283751560ab1d90b82ba4bb8d54d818401c1882448ed528d5b36312471cfbd6a9c6cd26a0cfbe1ae81b99d9bb379aaecd61087aa8c88132ac416858f7e5f38f9aa7a9065bd5072fa3a704efeb1dc71a1fe81217fcd0f32bd7323c77c42889e2933ff259f07776fc1ab9e39d9762f0b508cfa84ef582692b7f1386ad7fa8b6279fa5cc68386ce912e0371d68758f38cbf7e80d31edd7dcb8c85a97c6d930b799e08a1fdbd93c363fd8fe57e72ee1d278d7a004b66d4b99b8a663f049a18dc9edfc959fee2058a1360107dea0debabea6b8764e8034e2cf39b99941f4db74b8ccac5c52475a2c952d04823b498c91caf0681287aa245b3464e2a536b19ada372457485194d55f5777d4cf2ae6aa4bc6798df4eb9c505856f518923572034d3f2213a70d1428fb623cb00bd584cac196f2914e84fe9163a2809cff8b8fbb61a25fb20d0d2407c0d33b30ecb2d9f0be18bbc4ee635f6cbe108bd48a58b94fb96e0c90d855e0669b6aa6c9d7e38ace63f55e6c9c40f902f6248a1729e55fc74686851a5e5696a30ee9ca4e550793d5a60cfcacc874b7d97d091af27ecea78b0a25786c74a3b55eaeb6a503e930263ddd43f76e83383be5cf5c623deb3a5a266cd7961bb5b45fec00fa2c45745f3315fe648f4a4017d677b4cb1ff233447044dac90699922bc85bb3bd9e025c88c3d84f2205dede2db635e06e1071a60fb671bd6d45cab1da0cb9108395c9db91de87f457b919ffa8b8a7fb0b2af8c30e3e36b84107f48df04f7c1ccd5f3b582f53914848e7ef48cd0ec45cfc2fa3ee762bf9f5e6ad43b77e713a5ff0e1fbfe65a71c906ba4038de7c741ec51be4a2456dae849b29b5f574400b3488732ea0fe27d5aa8e989dfc95532a3a6eb5f903a4cd1c0fc912fddf5a15d03dd85c29568eafa8dd9521525ba06512c2a0e9a3b699e63942885e66d3ab37cd97d94920a6ba7774a1939d86b7e6285c27e25ff85feccf5a54fe6d03ede451062bbcc87b88507c444c94e0b4329902025d35dae28c4cdb47a36944c6f88ea63a1785c0a996433ca9088d78ea38bf189399441a257dc5f30bc8d6a364a8c0cc686581519cffd98cf71adfa6f37ac6ffd7e1db1abe5e45ca19f3e3c88edc1b788d7664567b040c77e62f8243e7c973eead829af5787d33fbae4570ca99a73dc3421cdd22004f646d928d3dfb9d966abb86f4f76c18d1029043bf823234f5cbfea5c726dc7ed1b5f585b51caf1b131f41afb90109d08f9575976ba47e32a2721681c791bcdf02c8f4f0159e8d69cefc2f0ca0f63e43bb4b42a607322bd68e259e79bb1238ad2bdbf6390470204485a29ecc690ad0ca73f2ffb1728701935d7aa556aa795f719b7af4a6d705ceca1796a8caa3d48be247c9c28343af68d22676c162eceb0"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
